/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * RouterSettingsFrame.java
 *
 * Created on 2010-04-12, 19:13:43
 */

package nsdh.view;

import nsdh.*;
import nsdh.model.script_models.*;
import javax.swing.*;
import javax.swing.table.*;
import java.util.*;
import javax.swing.event.*;

/**
 *
 * @author vtq
 */
public class RouterSettingsFrame extends javax.swing.JFrame {

    /**
     * Konstruktor tworzacy okno edycji ustawien routera
     * @param routerName - nazwa routera
     */
    public RouterSettingsFrame(NsdhController nsdhController, GraphPanel graphPanel, String routerName) {
        super();
        initComponents();
        this.nsdhController = nsdhController;
        this.graphPanel = graphPanel;
        this.routerName = routerName;

        routerNameTextField.setText(routerName);
        createRoutingTableFields();
        LoadRoutingTableFromNsdhModel();
        this.setLocationRelativeTo(null);
        this.setVisible(true);
        
    }

    /**
     * Konstruktor tworzacy okno dodawania nowego Routera
     */
    public RouterSettingsFrame(NsdhController nsdhController, GraphPanel graphPanel) {
        super();
        initComponents();
        this.nsdhController = nsdhController;
        this.graphPanel = graphPanel;
        this.routerName = null;

        routerNameTextField.setText("Router" + nsdhController.nsdhModel.sequences.routerSequence);
        createRoutingTableFields();
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        routerNameTextField = new javax.swing.JTextField();
        routerNameLabel = new javax.swing.JLabel();
        okButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        routingTablePanel = new javax.swing.JPanel();
        routingTableScrollPane = new javax.swing.JScrollPane();
        routingTable = new javax.swing.JTable();
        removeRoutingTableRowButton = new javax.swing.JButton();
        addRoutingTableRowButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Parametry Routera");
        setAlwaysOnTop(true);
        setBounds(new java.awt.Rectangle(100, 50, 0, 0));
        setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        setResizable(false);

        routerNameLabel.setText("Nazwa:");

        okButton.setText("OK");
        okButton.setActionCommand("jButton1");
        okButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okButtonActionPerformed(evt);
            }
        });

        cancelButton.setText("Anuluj");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        routingTablePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Tablica Routingu (dla trybu manualnego)"));

        routingTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        routingTableScrollPane.setViewportView(routingTable);

        removeRoutingTableRowButton.setText("Usun");
        removeRoutingTableRowButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeRoutingTableRowButtonActionPerformed(evt);
            }
        });

        addRoutingTableRowButton.setText("Dodaj");
        addRoutingTableRowButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addRoutingTableRowButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout routingTablePanelLayout = new javax.swing.GroupLayout(routingTablePanel);
        routingTablePanel.setLayout(routingTablePanelLayout);
        routingTablePanelLayout.setHorizontalGroup(
            routingTablePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(routingTablePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(routingTableScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 303, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(routingTablePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(removeRoutingTableRowButton, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(addRoutingTableRowButton, javax.swing.GroupLayout.DEFAULT_SIZE, 75, Short.MAX_VALUE))
                .addContainerGap())
        );
        routingTablePanelLayout.setVerticalGroup(
            routingTablePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(routingTablePanelLayout.createSequentialGroup()
                .addGroup(routingTablePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(routingTablePanelLayout.createSequentialGroup()
                        .addComponent(addRoutingTableRowButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(removeRoutingTableRowButton))
                    .addComponent(routingTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 251, Short.MAX_VALUE))
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(routerNameLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(routerNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 262, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(123, 123, 123)
                        .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(routingTablePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(routerNameLabel)
                    .addComponent(routerNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(routingTablePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(24, 24, 24)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(okButton)
                    .addComponent(cancelButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed

        try{

            graphPanel.saveCellsToNsdhModel();

            //tworzy router na podstawie ekranu
            Router router = new Router();

            //sprawdz czy nazwa sie nie powtarza
            if( !routerNameTextField.getText().equals(routerName) && nsdhController.nsdhModel.network_structure.router_list.containsKey(routerNameTextField.getText())){
                throw new Exception("Router o takiej nazwie juz istnieje, zmien nazwe.");
            }
            else if(routerNameTextField.getText()==null || routerNameTextField.getText().equals("")){
                throw new Exception("Nazwa krawedzi nie moze byc pusta");
            }else if (nsdhController.nsdhModel.network_structure.pc_list.containsKey(routerNameTextField.getText())){
                throw new Exception("Nazwy węzłów w grafie nie mogą się powtarzać. Pc o takiej nazwie już istnieje.");
            }
            else{
                router.name = routerNameTextField.getText();
            }


            //gdy edycja obiektu
            if(routerName!=null && nsdhController.nsdhModel.network_structure.router_list.containsKey(routerName)){

                //zapisz x,y i tablice routingu do routera tymczasowego:
                router.gui_x = nsdhController.nsdhModel.network_structure.router_list.get(routerName).gui_x;
                router.gui_y = nsdhController.nsdhModel.network_structure.router_list.get(routerName).gui_y;
                SaveRoutingTableToTempRouter(router);

                //zmien nazwe w modelu calym
                nsdhController.RenameRouter(routerName, router.name);
                
                //podmien router
                nsdhController.nsdhModel.network_structure.router_list.put(router.name, router);

            }
            else{ //gdy dodanie nowego obiektu

                //pobiera wolne miejsce na grafie i zapis tablicy rutowania
                String[] sparePlaceXY = graphPanel.getSparePlaceXY();
                router.gui_x = sparePlaceXY[0];
                router.gui_y = sparePlaceXY[1];
                SaveRoutingTableToTempRouter(router);

                nsdhController.nsdhModel.network_structure.router_list.put(router.name, router);

                //zwieksz numer sekwencyjny
            nsdhController.nsdhModel.sequences.routerSequence++;
            }

            //zaktualizuj graf
            graphPanel.loadAllFromNsdhModel();

            this.dispose();

        }catch(Exception e){
            JOptionPane.showMessageDialog(this, e.getMessage(), "Ostrzeżenie", JOptionPane.WARNING_MESSAGE);
        }
    }//GEN-LAST:event_okButtonActionPerformed

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        this.dispose();
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void addRoutingTableRowButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addRoutingTableRowButtonActionPerformed
        DefaultTableModel model = (DefaultTableModel)routingTable.getModel();
        Object[] newRow = {"",""};

        
        if(routingTable.getSelectedRow()!=-1){

            if(routingTable.getCellEditor()!=null){
                routingTable.getCellEditor().stopCellEditing();
            }

            
            model.fireTableDataChanged();
            model.insertRow(routingTable.getSelectedRow()+1, newRow);
            model.fireTableDataChanged();
            
            routingTable.requestFocusInWindow();
        }else{
            if(routingTable.isEditing()){
                routingTable.editingStopped(new ChangeEvent(addRoutingTableRowButton));
            }
            model.fireTableDataChanged();
            model.insertRow(model.getRowCount(), newRow);
            model.fireTableDataChanged();

            routingTable.requestFocusInWindow();
        }
        
    }//GEN-LAST:event_addRoutingTableRowButtonActionPerformed

    private void removeRoutingTableRowButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeRoutingTableRowButtonActionPerformed
        // TODO add your handling code here:

        DefaultTableModel model = (DefaultTableModel)routingTable.getModel();

        int[] selectedRows = routingTable.getSelectedRows();

        java.util.Arrays.sort(selectedRows);
        for(int i=selectedRows.length-1; i>= 0; i--){
            if(routingTable.isEditing()){
                routingTable.editingStopped(new ChangeEvent(removeRoutingTableRowButton));
            }
            model.fireTableDataChanged();
            model.removeRow(selectedRows[i]);
            model.fireTableDataChanged();

            routingTable.requestFocusInWindow();

        }


    }//GEN-LAST:event_removeRoutingTableRowButtonActionPerformed


    private void createRoutingTableFields(){

        //zainicjalizuj model tabeli
        String[] values = new String[]{"Cel Pakietu", "Next Hop"};
        routingTable.setModel(new DefaultTableModel(values,0));
        DefaultTableModel model = (DefaultTableModel)routingTable.getModel();

        //tablica PC na grafie
        Set<String> dstPcNameSet = new HashSet(nsdhController.nsdhModel.network_structure.pc_list.keySet());
        dstPcNameSet.add("");
        Object[] dstPcNameArray = dstPcNameSet.toArray();
        java.util.Arrays.sort(dstPcNameArray);

        //utworz combobox celu pakietu
        JComboBox dstComboBox = new JComboBox();
        dstComboBox.setModel(new javax.swing.DefaultComboBoxModel(dstPcNameArray));

        //next_hop combo box
        Set<String> cellNameSet = new HashSet(nsdhController.getNearbyNodes(routerName));
        cellNameSet.add("");
        Object[] cellNameArray = cellNameSet.toArray();
        java.util.Arrays.sort(cellNameArray);
        JComboBox nextHopComboBox = new JComboBox();
        nextHopComboBox.setModel(new javax.swing.DefaultComboBoxModel(cellNameArray));


        //dodaje combox do tabeli
        routingTable.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(dstComboBox));
        routingTable.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(nextHopComboBox));


        pack();
    }


    private void LoadRoutingTableFromNsdhModel(){


        DefaultTableModel model = (DefaultTableModel)routingTable.getModel();

        //wyczysc tabele
        int rowsNum = routingTable.getRowCount();
        for(int i=rowsNum-1; i>= 0; i--){
            model.removeRow(i);
        }

        //dodaj do tabeli wiersze z modelu
        for(Routing_table_row routing_table_row: nsdhController.nsdhModel.network_structure.router_list.get(routerName).routing_table_row_list){
            String[] routing_table_rowArray = new String[2];
            routing_table_rowArray[0]= routing_table_row.packet_destination;
            routing_table_rowArray[1]= routing_table_row.next_hop;

            model.insertRow(model.getRowCount(), routing_table_rowArray);
        }

    }

    private void SaveRoutingTableToTempRouter(Router router) throws Exception{


        DefaultTableModel model = (DefaultTableModel)routingTable.getModel();

        //tymczasowa tabela ze zdarzeniami
        ArrayList<Routing_table_row> tempRowList = new ArrayList<Routing_table_row>();

        //dodaj wszystkie wiersze do tabeli ze zdarzeniami
        for(int i=0; i< model.getRowCount();i++){
            Routing_table_row routing_table_row = new Routing_table_row();

            if((String)model.getValueAt(i, 0)!=null && !((String)model.getValueAt(i, 0)).equals("")){
                routing_table_row.packet_destination=(String)model.getValueAt(i, 0);
            }else{
                throw new Exception("Packet destination nie moze byc puste.");
            }

            if((String)model.getValueAt(i, 1)!=null && !((String)model.getValueAt(i, 1)).equals("")){
                routing_table_row.next_hop=(String)model.getValueAt(i, 1);
            }else{
                throw new Exception("Packet destination nie moze byc puste.");
            }

            tempRowList.add(routing_table_row);
        }

        router.routing_table_row_list = tempRowList;

    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addRoutingTableRowButton;
    private javax.swing.JButton cancelButton;
    private javax.swing.JButton okButton;
    private javax.swing.JButton removeRoutingTableRowButton;
    private javax.swing.JLabel routerNameLabel;
    private javax.swing.JTextField routerNameTextField;
    private javax.swing.JTable routingTable;
    private javax.swing.JPanel routingTablePanel;
    private javax.swing.JScrollPane routingTableScrollPane;
    // End of variables declaration//GEN-END:variables
    private NsdhController nsdhController;
    private GraphPanel graphPanel;
    private String routerName;
}
